<!-- 为解决row-key导致的多选框点击后总按钮显示问题，加入isSetRowKey判断，列表若有层级，父组件需传isSetRowKey，以及row-key -->
<template>
  <div style="height: 100%; width: 100%">
    <el-table
      class="global-common-table"
      v-if="isSetRowKey"
      style="width: 100%"
      cell-class-name="global-common-table-cell"
      :data="tableData"
      ref="table"
      :height="height"
      :row-key="getRowKey"
      :tree-props="treeProps"
      :header-cell-style="headerCellStyle"
      @select="selectData"
      @cell-click="cellClick"
      header-cell-class-name="global-common-table-header-cell"
      @sort-change="sortChange"
      @selection-change="$emit('selection-change', $event)"
    >
      <template slot="empty">
        <div class="table-tooltip">
          <i class="iconfont icon-wushuju"></i>
          <span class="tip-content">暂无数据</span>
        </div>
      </template>

      <template v-if="tableField.length">
        <el-table-column v-for="f in tableField" :key="f.key" v-bind="f">
        </el-table-column>
      </template>
      <template v-else>
        <slot></slot>
      </template>
    </el-table>
    <el-table
      class="global-common-table"
      v-else
      style="width: 100%"
      cell-class-name="global-common-table-cell"
      :data="tableData"
      :border="border"
      ref="table"
      :key="dataKey"
      :height="height"
      :tree-props="treeProps"
      :default-sort="defaultSort"
      :span-method="spanMethod"
      :header-cell-style="headerCellStyle"
      @select="selectData"
      @cell-click="cellClick"
      header-cell-class-name="global-common-table-header-cell"
      @sort-change="sortChange"
      @selection-change="$emit('selection-change', $event)"
    >
      <template slot="empty">
        <div class="table-tooltip">
          <i class="iconfont icon-wushuju"></i>
          <span class="tip-content">暂无数据</span>
        </div>
      </template>
      <template v-if="tableField.length">
        <el-table-column v-for="f in tableField" :key="f.key" v-bind="f">
        </el-table-column>
      </template>
      <template v-else>
        <slot></slot>
      </template>
    </el-table>
  </div>
</template>

<script>
export default {
  name: "CommonTable",
  props: {
    data: {
      type: Array,
      default: () => [],
    },
    field: {
      type: Array,
      default: () => [
        /*  {
            key:'',
            prop:'',
            label:''
          }*/
      ],
    },
    height: {
      type: String,
      default: "100%",
    },
    treeProps: {
      type: Object,
    },
    rowKey: {
      type: String || Function,
    },
    isSetRowKey: {
      type: Boolean,
      default: () => false,
    },
    isInputTable: {
      type: Boolean,
      default: () => false,
    }, // 是否是输入型表格
    defaultSort: {
      type: Object,
    },
    border: {
      type: Boolean,
      default: () => false,
    },
    spanMethod: {
      type: Function,
    },
    headerCellStyle: {
      type: Object,
      default: () => {},
    },
  },
  computed: {
    dataKey() {
      return this.isInputTable ? null : JSON.stringify(this.data);
    },
    tableField: function () {
      let tableField = this.field || [];
      if (tableField && tableField instanceof Array) {
        return tableField.reduce((r, c) => {
          if (c.type === "selection") {
            r.push(c);
          } else {
            // 解决带.的key数据不展示问题
            r.push({
              ...c,
              prop: c.prop ? c.prop.replaceAll(/\./g, "__") : c.prop,
            });
          }
          return r;
        }, []);
      } else {
        return [];
      }
    },
    tableData: function () {
      let tableData = this.data || [];
      if (tableData && tableData instanceof Array) {
        if (tableData.length) {
          let keys = Object.keys(tableData[0]).filter((key) => /\./g.test(key));

          if (keys.length) {
            return tableData.reduce((r, c) => {
              let result = {
                ...c,
              };
              keys.forEach((key) => {
                let newKey = key.replaceAll(/\./g, "__");
                result[newKey] = c[key];
              });

              r.push(result);
              return r;
            }, []);
          } else {
            return tableData;
          }
        } else {
          return tableData;
        }
      } else {
        return [];
      }
    },
  },
  watch: {
    data: function () {
      this.handleSelection();
    },
  },
  methods: {
    handleSelection() {
      if (this.$slots.default && this.$slots.default instanceof Array) {
        // 存在子元素
        let selection = this.$slots.default.find((node) => {
          return node.componentOptions?.propsData?.type === "selection";
        });

        if (selection) {
          // 存在复选框

          this.$nextTick(() => {
            // 数据变化之后重置复选框绑定的数据
            let selection = this.$refs.table.selection;
            this.$emit("selection-change", selection);
          });
        } else {
          // 不存在复选框
        }
      }
    },
    getRowKey(row) {
      return row[this.rowKey];
    },
    selectData(val, row) {
      this.$emit("select", { list: val, data: row });
    },
    cellClick(row, column, cell, event) {
      this.$emit("cell-click", {
        row,
        column,
        cell,
        event,
      });
    },
    sortChange(column, prop, order) {
      this.$emit("sort-change", column);
    },
  },
};
</script>

<style scoped lang="scss">
.global-common-table {
  position: relative;
  /*border: 1px solid #eee;*/
  /*border-bottom: 0;*/
  /*height: calc(100% - 18px);*/
  margin-top: 0 !important;
}

::v-deep .global-common-table-header-cell {
  font-size: 14px;

  color: #909399;

  .cell {
    /*font-weight: bolder!important;*/
  }
}

::v-deep .global-common-table-cell {
  font-size: 14px;
}

.table-tooltip {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;

  .icon-wushuju {
    font-size: 40px;
    line-height: 40px;
  }

  .tip-content {
    line-height: 32px;
  }
}

::v-deep .el-table__body {
  // 使表格兼容safari，不错位
  width: 100%;
  table-layout: fixed !important;
}
</style>
